using Sunny.UI;
using System.IO.Ports;
using System.Text;

namespace 串口通信Demo
{
    public partial class FrmMain : UIForm
    {
        public FrmMain()
        {
            InitializeComponent();
            Init();
        }

        private void Init()
        {
            //端口号
            string[] portList = SerialPort.GetPortNames();
            if (portList.Length > 0)
            {
                this.cb_PortName.DataSource = portList;
                this.cb_PortName.SelectedIndex = 0;
            }

            //波特率
            this.cb_BaudRate.DataSource = new string[] { "9600", "19200", "38400", "57600", "115200" };
            this.cb_BaudRate.SelectedIndex = 0;

            //数据位
            this.cb_DataBits.DataSource = new string[] { "7", "8" };
            this.cb_DataBits.SelectedIndex = 0;

            //校验位
            this.cb_Parity.DataSource = Enum.GetNames(typeof(Parity));
            this.cb_Parity.SelectedIndex = 0;

            //停止位
            this.cb_StopBits.DataSource = Enum.GetNames(typeof(StopBits));
            this.cb_StopBits.SelectedIndex = 1;

            this.led_State.On = false;

            this.timer_Send.Interval = 1000;
            this.timer_Send.Enabled = false;
            this.timer_Send.Tick += Timer_Send_Tick;

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);


        }

        private void Timer_Send_Tick(object? sender, EventArgs e)
        {
            SendData();
        }

        private void SendData()
        {
            if (serialPort.IsOpen)
            {
                string sendData = this.txt_Send.Text.Replace(" ","");
                
                if (sendData == string.Empty)
                {
                    UIMessageTip.ShowWarning("请输入要发送的数据！");
                    return;
                }
                if (this.ck_HexSend.Checked)
                {
                    try
                    {
                        //两个十六进制字符代表一个字节
                        byte[] sendBytes = new byte[sendData.Length / 2];
                        for (int i = 0; i < sendData.Length / 2; i++)
                        {
                            sendBytes[i] = Convert.ToByte(sendData.Substring(i * 2, 2), 16);
                        }
                        serialPort.Write(sendBytes, 0, sendBytes.Length);
                    }
                    catch (Exception ex)
                    {

                        UIMessageTip.ShowWarning("16进制格式不对");
                        return;
                    }
                   
                }
                else
                {
                    
                    byte[] sendBytes = Encoding.GetEncoding("GB2312").GetBytes(sendData);
                    serialPort.Write(sendBytes, 0, sendBytes.Length);
                }
                UIMessageTip.ShowOk("已发送：" + sendData);
            }
            else
            {
                UIMessageTip.ShowWarning("请先打开串口！");
            }
        }



        private SerialPort serialPort = new SerialPort();


        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Open_Click(object sender, EventArgs e)
        {
            if (this.btn_Open.Text == "打开串口")
            {
                serialPort.PortName = this.cb_PortName.Text;
                serialPort.BaudRate = int.Parse(this.cb_BaudRate.Text);
                serialPort.DataBits = int.Parse(this.cb_DataBits.Text);
                serialPort.Parity = (Parity)Enum.Parse(typeof(Parity), this.cb_Parity.Text);
                serialPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), this.cb_StopBits.Text);
                serialPort.RtsEnable = this.ck_RTS.Checked;
                serialPort.DtrEnable = this.ck_DTR.Checked;
                serialPort.Encoding = System.Text.Encoding.GetEncoding("GB2312");
              
                if (!serialPort.IsOpen)
                {
                    try
                    {
                        serialPort.Open();
                        serialPort.DataReceived += SerialPort_DataReceived;
                        this.led_State.On = true;
                        UIMessageTip.ShowOk("串口已打开！");
                        this.btn_Open.Text = "关闭串口";
                        this.btn_Open.BackColor = Color.Green;
                    }
                    catch (Exception ex)
                    {

                        UIMessageBox.ShowError("打开串口失败！" + ex.Message);
                        return;
                    }
                   
                }
                else
                {
                    UIMessageTip.ShowWarning("串口已经打开");
                    this.led_State.On = false;
                }
            }
            else
            {
                if (serialPort.IsOpen)
                {
                    this.serialPort.Close();
                    this.btn_Open.Text = "打开串口";
                    this.led_State.On = false;
                    UIMessageTip.ShowOk("串口已关闭！");
                }
            }
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (this.ck_HexSend.Checked)
            {
                //定义一个字节数组
                try
                {
                    //定义最终的字符串
                    string revStr = string.Empty;
                    //它告诉你当前有多少字节的数据已经在缓冲区中等待被读取
                    byte[] data = new byte[serialPort.BytesToRead];

                    //读取缓冲区值到字节数组
                    this.serialPort.Read(data, 0, data.Length);

                    //拼接显示
                    foreach (byte item in data)
                    {
                        string hex = Convert.ToString(item, 16).ToUpper();

                        revStr += (hex.Length == 1 ? "0" + hex : hex) + " ";
                    }

                    this.txt_Rev.Invoke(new Action(() =>
                    {
                        //接收
                        this.txt_Rev.AppendText("接收到数据：" + revStr + Environment.NewLine);
                    }));


                }

                catch (Exception ex)
                {
                    this.txt_Rev.Invoke(new Action(() =>
                    {
                        //接收
                        this.txt_Rev.AppendText("接收出现错误：" + ex.Message + Environment.NewLine);

                    }));
                }
            }
            else
            {
                //用于读取串口接收缓冲区中的所有立即可用数据，并将其作为字符串返回
                string revStr = serialPort.ReadExisting();
                this.txt_Rev.Invoke(new Action(() =>
                {
                    this.txt_Rev.AppendText("接收到数据：" + revStr + Environment.NewLine);

                }));

            }
        }

        private void btn_Send_Click(object sender, EventArgs e)
        {
            SendData();
        }

        private void ck_DTR_CheckedChanged(object sender, EventArgs e)
        {
            this.serialPort.RtsEnable = this.ck_DTR.Checked;
        }

        private void ck_RTS_CheckedChanged(object sender, EventArgs e)
        {
            this.serialPort.DtrEnable = this.ck_RTS.Checked;
        }

        private void ck_AutoSend_CheckedChanged(object sender, EventArgs e)
        {
            if (this.ck_AutoSend.Checked)
            {
                this.timer_Send.Enabled = true;
            }
            else
            {
                this.timer_Send.Enabled = false;
            }
        }


    }
}
